
#ifndef BYTE_DECODE_H_
#define BYTE_DECODE_H_

#include <algorithm>
#include <bitset>
#include <iostream>

constexpr int32_t BYTE_LENGTH = static_cast<int32_t>(sizeof(int8_t) * 8);

const uint8_t RANG_MASK_1_L[] = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
const uint8_t RANG_MASK_0_L[] = {0xFE, 0XFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00};

class Byte
{
public:
    explicit Byte(const uint8_t *value);
    Byte(const Byte &value);
    ~Byte() = default;
    static std::string byte_to_hex(const uint8_t value);
    static std::string byte_to_hex(const uint32_t value);
    static std::string byte_to_binary(const uint8_t value);
    void set_bit_1(const int32_t pos);
    void set_bit_0(const int32_t pos);
    bool is_bit_1(const int32_t pos) const;
    void set_value(const uint8_t value);
    void set_value_high_4_bits(const uint8_t value);
    void set_value_low_4_bits(const uint8_t value);
    void set_value(const uint8_t value, const int32_t start_pos, const int32_t length);

    uint8_t get_byte() const;
    uint8_t get_byte_high_4_bits() const;
    uint8_t get_byte_low_4_bits() const;
    uint8_t get_byte(const int32_t start_pos, const int32_t length) const;

    std::string to_hex_string() const;
    std::string to_binary_string() const;

private:
    uint8_t *value_;
};


#endif